package hephaestus.server.proxy;

import hephaestus.common.*;

import java.io.IOException;
import java.net.*;

public class IncomingConnection extends Thread {
	private ConnectionManager connections;
	private String internalAddressPrefix;
	private IncomingManager manager;
	private Connection client;
	
	public IncomingConnection(ConnectionManager connections, IncomingManager manager, String internalAddressPrefix, Socket client)
	{
		this.internalAddressPrefix = internalAddressPrefix;
		this.connections = connections;
		this.manager = manager;
		try {
			this.client = new Connection(client);
		} catch (IOException e) {
			e.printStackTrace();
			this.client = null;
		}
	}
	
	private boolean validateInternalIP()
	{
		String clientIP = client.getIP();
		return clientIP.startsWith(internalAddressPrefix);
	}
	
	public void run()
	{
		try
		{
			String message = client.receive();
			String[] parts = message.split(" ");
			if(parts.length < 1)
			{
				client.send("error invalid-message");
				client.close();
			}
			else if(parts.length < 2)
			{
				client.send("error too-few-params");
				client.close();
			}
			else if(parts[0].equals("internal"))
			{
				if(validateInternalIP())
				{
					if(parts[1].equals("auth-server"))
					{
						if(!connections.hasAuthenticationServer())
						{
							System.out.println("# Authentication server registered [" + client.getIP() + "]");
							connections.registerAuthenticationServer(client);
							client.send("okay");
						}
						else
						{
							client.send("error already-have-auth");
							client.close();
						}
					}
					else if(parts[1].equals("game-server"))
					{
						if(parts.length >= 3)
						{
							if(!connections.hasGameServerCalled(parts[2]))
							{
								System.out.println("# Game server '" + parts[2] + "' registered [" + client.getIP() + "]");
								connections.registerGameServer(client, parts[2]);
								client.send("okay");
							}
							else
							{
								client.send("error area-name-taken");
								client.close();
							}
						}
						else
						{
							client.send("error too-few-params");
							client.close();
						}
					}
					else
					{
						client.send("error invalid-server-type");
						client.close();
					}
				}
				else
				{
					System.out.println("! External IP attempting to register as internal [" + client.getIP() + "]");
					client.send("error ip-not-internal");
					client.close();
				}
			}
			else if(parts[0].equals("login"))
			{
				if(parts.length >= 3)
				{
					if(!connections.isAlreadyConnected(parts[1]))
					{
						if(connections.authenticate(parts[1], parts[2]))
						{
							long authID = connections.clientConnected(parts[1], client);
							if(authID != ClientConnection.INVALID_AUTH_ID)
							{
								client.send("okay " + authID);
							}
						}
						else
						{
							client.send("error incorrect-login-details");
							client.close();
						}
					}
					else
					{
						client.send("error already-connected");
						client.close();
					}
				}
				else
				{
					client.send("error too-few-params");
					client.close();
				}
			}
			else
			{
				client.send("error invalid-message-type");
				client.close();
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		manager.dequeueIncomingConnection(this);
	}
}
